#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>

void hander(int sig)
{
    printf("This is SINPIPE\n");
}

int main()
{
    int pipefd[2];
    if(pipe(pipefd) == -1)
    {
        perror("fail to pipe");
        exit(-1);
    }
    #if 0
    write(pipefd[1],"hello wrold",12);
    //读写端都存在，只读不写，读端将会阻塞
    char buf[12] = "";
    while(1)
    {
        if(read(pipefd[0],buf,12)==-1)
        {
            printf("fail to read");
            exit(-1);
        }
        printf("buf = %s\n",buf);
    }
    #endif
    #if 0
    //读写端都存在，只写不读，缓存区写满后，将会阻塞
    int count = 0;
    while(1)
    {
        if(write(pipefd[1],"hello",1024)==-1)
        {
            printf("fail to write");
            exit(-1);
        }
        count++;
        printf("w_count = %d\n",count);   //count_max = 64
    }
    #endif
    #if 0
    write(pipefd[1],"hello wrold",12);
    //关闭写端，管道有数据，正常读取，管道没有数据，read函数会返回0
    close(pipefd[1]);
    char buf[12] = "";
    ssize_t bytes = 0;
    if((bytes = read(pipefd[0],buf,12))==-1)
    {
        printf("fail to read");
        exit(-1);
    }
    printf("第一次读取 buf = %s\n",buf);
    printf("bytes = %ld\n",bytes); //12
    memset(buf,0,sizeof(buf));
    if((bytes = read(pipefd[0],buf,12))==-1)
    {
        printf("fail to read");
        exit(-1);
    }
    printf("第二次读取 buf = %s\n",buf);
    printf("bytes = %ld\n",bytes);  //0
    #endif

    #if 1
    //关闭读端，执行写操作时，写进程会立即发送SIGPIPE信号（默认退出进程）
    if(signal(SIGPIPE,hander) == SIG_ERR)
    {
        perror("fail to signal");
        exit(-1);
    }
    close(pipefd[0]);
    
    if(write(pipefd[1],"hello",1024)==-1)
    {
        perror("fail to write");
        exit(-1);
    }
    #endif
    return 0;
}